package aiP.A3.PersistenceService;


import aiP.A3.AuftragKomponente.DataAccessLayer.Entity.Angebot;
import aiP.A3.AuftragKomponente.DataAccessLayer.Entity.Auftrag;
import aiP.A3.BuchhaltungKomponente.DataAccessLayer.Entity.Kunde;
import aiP.A3.BuchhaltungKomponente.DataAccessLayer.Entity.Rechnung;
import aiP.A3.BuchhaltungKomponente.DataAccessLayer.Entity.Zahlungseingang;
import aiP.A3.FertigungKomponente.DataAccessLayer.Entity.Bauteil;
import aiP.A3.VersandKomponente.DataAccessLayer.Entity.Transportauftrag;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: mizus
 * Date: 15.05.14
 * Time: 13:13
 * To change this template use File | Settings | File Templates.
 */

public class Persist {

    private Persist() {}

    private static Persist instance;
    private static final SessionFactory ourSessionFactory;
    private static final ServiceRegistry serviceRegistry;

    public static Persist getInstance(){
        if (instance==null) instance = new Persist();
        return instance;
    }

    static {
        try {
            Configuration configuration = new Configuration();
            configuration.configure();
            serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
            ourSessionFactory = configuration.buildSessionFactory(serviceRegistry);
        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
    }

    public Session getSession() throws HibernateException {
        return ourSessionFactory.openSession();
    }



    public void save(iEntity toSave){
        final Session session = getSession();

        Transaction tx =  session.beginTransaction();
        System.err.println("isOpen: " +  session.isConnected() + " " + tx.isActive());
        System.out.println("iEntity: " + toSave);

        session.saveOrUpdate(toSave);

        tx.commit();

        session.close();
    }

    public Collection<iEntity> load(int aTyp){
        Collection<iEntity> result = null;
        switch(aTyp){
            case iEntity.ANGEBOT:
                result = load_persist(Angebot.class.getName());
               break;
            case iEntity.AUFTRAG:
                result = load_persist(Auftrag.class.getName());
                break;
            case iEntity.BAUTEIL:
                 result = load_persist(Bauteil.class.getName());
                break;
            case iEntity.FERTIGUNGSPLAN:
               //  load_persist()
                break;
            case iEntity.KUNDE:
                result = load_persist(Kunde.class.getName());
                break;
            case iEntity.RECHNUNG:
                result = load_persist(Rechnung.class.getName());
                break;
            case iEntity.TRANSPORTAUFTRAG:
                result = load_persist(Transportauftrag.class.getName());
                break;
            case iEntity.ZAHLUNGSEINGANG:
                result = load_persist(Zahlungseingang.class.getName());
                break;
        }
        return result;
    }


    private Set<iEntity> load_persist(String typ){
        Set<iEntity> result = new HashSet<iEntity>();
        final Session session = getSession();
        try {
            System.out.println("querying all the managed entities...");
            final Map metadataMap = session.getSessionFactory().getAllClassMetadata();
            for (Object key : metadataMap.keySet()) {
                final ClassMetadata classMetadata = (ClassMetadata) metadataMap.get(key);
                //final String entityName = classMetadata.getEntityName();

                String dbQuery = "from " + typ;
               // System.out.println(dbQuery);
                final Query query = session.createQuery(dbQuery);
               // System.out.println("executing: " + query.getQueryString() + " Size: " + query.list().size());
                for (Object o : query.list()) {
                    result.add((iEntity)o);
                }
            }
        } finally {
            session.close();
        }
        return result;
    }

}
